home *** CD-ROM | disk | FTP | other *** search
/ AmigActive 10 / AACD 10.iso / AACD / Games / MAME / src / vidhrdw / astrocde.c < prev    next >
C/C++ Source or Header  |  2000-05-25  |  18KB  |  851 lines

  1. /***************************************************************************
  2.  
  3.   vidhrdw.c
  4.  
  5.   Functions to emulate the video hardware of the machine.
  6.  
  7. ***************************************************************************/
  8.  
  9. #include "driver.h"
  10. #include "cpu/z80/z80.h"
  11.  
  12. #include <math.h> /* for sin() and cos() */
  13.  
  14.  
  15. #define SCREEN_WIDTH 320
  16. #define MAX_LINES 204
  17.  
  18. #define MAX_INT_PER_FRAME 256
  19.  
  20. unsigned char *wow_videoram;
  21. static int magic_expand_color, magic_control, magic_expand_count, magic_shift_leftover;
  22. static int collision;
  23.  
  24. /* This value affects the star layout, the value is correct since
  25.    it is mentioned in the docs and perfectly matches screen shots.
  26.  */
  27. #define CLOCKS_PER_LINE 455
  28.  
  29. /* This value affects the star blinking and the sparkle patterns.
  30.    It is just a guess, aiming to a supposed 60Hz refresh rate, and has
  31.    not been verified.
  32.  */
  33. #define CLOCKS_PER_FRAME (CLOCKS_PER_LINE*262)
  34.  
  35. #define RNG_PERIOD 131071    /* 2^17-1 */
  36. static int *rng;
  37. static int *star;
  38.  
  39.  
  40. static int colors[MAX_INT_PER_FRAME][8];
  41. static int colorsplit[MAX_INT_PER_FRAME];
  42. static int BackgroundData,VerticalBlank;
  43.  
  44. static int sparkle[MAX_INT_PER_FRAME][4];    /* sparkle[line][0] is star enable */
  45.  
  46.  
  47. void wow_update_line(struct osd_bitmap *bitmap,int line);
  48.  
  49.  
  50.  
  51. void astrocde_init_palette(unsigned char *palette, unsigned short *colortable,const unsigned char *color_prom)
  52. {
  53.     /* This routine builds a palette using a transformation from */
  54.     /* the YUV (Y, B-Y, R-Y) to the RGB color space */
  55.  
  56.     int i,j;
  57.  
  58.     float Y, RY, BY;    /* Y, R-Y, and B-Y signals as generated by the game */
  59.                         /* Y = Luminance -> (0 to 1) */
  60.                         /* R-Y = Color along R-Y axis -> C*(-1 to +1) */
  61.                         /* B-Y = Color along B-Y axis -> C*(-1 to +1) */
  62.     float R, G, B;
  63.  
  64.     float brightest = 1.0;    /* Approx. Luminance values for the extremes -> (0 to 1) */
  65.     float dimmest   = 0.0;
  66.     float C = 0.75;            /* Approx. Chroma intensity */
  67.  
  68.     /* The astrocade has a 256 color palette                 */
  69.     /* 32 colors, with 8 luminance levels for each color     */
  70.     /* The 32 colors circle around the YUV color space,      */
  71.     /* with the exception of the first 8 which are grayscale */
  72.  
  73.     /* Note: to simulate a B&W monitor, set C=0 and all      */
  74.     /*       colors will appear as the first 8 grayscales    */
  75.  
  76.     for(i=0;i<32;i++)
  77.     {
  78.         RY = C*sin(i*2.0*3.14159/32.0);
  79.         if (i == 0)
  80.             BY = 0;
  81.         else
  82.             BY = C*cos(i*2.0*3.14159/32.0);
  83.  
  84.         for(j=0;j<8;j++)
  85.         {
  86.             Y = (j/7.0)*(brightest-dimmest)+dimmest;
  87.  
  88.             /* Transform to RGB */
  89.  
  90.             R = (RY+Y)*255;
  91.             G = (Y - 0.299*(RY+Y) - 0.114*(BY+Y))/0.587*255;
  92.             B = (BY+Y)*255;
  93.  
  94.             /* Clipping, in case of saturation */
  95.  
  96.             if (R < 0)
  97.                 R = 0;
  98.             if (R > 255)
  99.                 R = 255;
  100.             if (G < 0)
  101.                 G = 0;
  102.             if (G > 255)
  103.                 G = 255;
  104.             if (B < 0)
  105.                 B = 0;
  106.             if (B > 255)
  107.                 B = 255;
  108.  
  109.             /* Round, and set the value */
  110.  
  111.             *palette = floor(R+.5);
  112.             palette++;
  113.             *palette = floor(G+.5);
  114.             palette++;
  115.             *palette = floor(B+.5);
  116.             palette++;
  117.         }
  118.     }
  119. }
  120.  
  121.  
  122.  
  123. /****************************************************************************
  124.  * Scanline Interrupt System
  125.  ****************************************************************************/
  126.  
  127. static int NextScanInt=0;            /* Normal */
  128. static int CurrentScan=0;
  129. static int InterruptFlag=0;
  130.  
  131. static int GorfDelay;                /* Gorf */
  132. static int Countdown=0;
  133.  
  134. WRITE_HANDLER( astrocde_interrupt_enable_w )
  135. {
  136.     InterruptFlag = data;
  137.  
  138.     if (data & 0x01)                    /* Disable Interrupts? */
  139.           interrupt_enable_w(0,0);
  140.     else
  141.           interrupt_enable_w(0,1);
  142.  
  143.     /* Gorf Special interrupt */
  144.  
  145.     if (data & 0x10)
  146.      {
  147.           GorfDelay =(CurrentScan + 7) & 0xFF;
  148.  
  149.         /* Gorf Special *MUST* occur before next scanline interrupt */
  150.  
  151.         if ((NextScanInt > CurrentScan) && (NextScanInt < GorfDelay))
  152.         {
  153.               GorfDelay = NextScanInt - 1;
  154.         }
  155.  
  156. #ifdef MAME_DEBUG
  157.         logerror("Gorf Delay set to %02x\n",GorfDelay);
  158. #endif
  159.  
  160.     }
  161.  
  162. #ifdef MAME_DEBUG
  163.     logerror("Interrupt Flag set to %02x\n",InterruptFlag);
  164. #endif
  165. }
  166.  
  167. WRITE_HANDLER( astrocde_interrupt_w )
  168. {
  169.     /* A write to 0F triggers an interrupt at that scanline */
  170.  
  171. #ifdef MAME_DEBUG
  172.     logerror("Scanline interrupt set to %02x\n",data);
  173. #endif
  174.  
  175.     NextScanInt = data;
  176. }
  177.  
  178. int wow_interrupt(void)
  179. {
  180.     int res,i,next;
  181.  
  182.     if (!osd_skip_this_frame())
  183.         wow_update_line(Machine->scrbitmap,CurrentScan);
  184.  
  185.     next = (CurrentScan + 1) % MAX_INT_PER_FRAME;
  186.     for (i = 0;i < 8;i++)
  187.         colors[next][i] = colors[CurrentScan][i];
  188.     for (i = 0;i < 4;i++)
  189.         sparkle[next][i] = sparkle[CurrentScan][i];
  190.     colorsplit[next] = colorsplit[CurrentScan];
  191.  
  192.     CurrentScan = next;
  193.  
  194.     /* Scanline interrupt enabled ? */
  195.  
  196.     res = ignore_interrupt();
  197.  
  198.     if ((InterruptFlag & 0x08) && (CurrentScan == NextScanInt))
  199.         res = interrupt();
  200.  
  201.     return res;
  202. }
  203.  
  204. /****************************************************************************
  205.  * Gorf - Interrupt routine and Timer hack
  206.  ****************************************************************************/
  207.  
  208. int gorf_interrupt(void)
  209. {
  210.     int res;
  211.  
  212.     res = wow_interrupt();
  213.  
  214.     /* Gorf Special Bits */
  215.  
  216.     if (Countdown>0) Countdown--;
  217.  
  218.     if ((InterruptFlag & 0x10) && (CurrentScan==GorfDelay))
  219.         res = interrupt() & 0xF0;
  220.  
  221. /*    cpu_clear_pending_interrupts(0); */
  222.  
  223. //    Z80_Clear_Pending_Interrupts();                    /* Temporary Fix */
  224.     cpu_set_irq_line(0,0,CLEAR_LINE);
  225.  
  226.     return res;
  227. }
  228.  
  229. /* ======================================================================= */
  230.  
  231. READ_HANDLER( wow_video_retrace_r )
  232. {
  233.     return CurrentScan;
  234. }
  235.  
  236. READ_HANDLER( wow_intercept_r )
  237. {
  238.     int res;
  239.  
  240.     res = collision;
  241.     collision = 0;
  242.  
  243.     return res;
  244. }
  245.  
  246.  
  247. /* Switches color registers at this zone - 40 zones (NOT USED) */
  248.  
  249. WRITE_HANDLER( astrocde_colour_split_w )
  250. {
  251.     colorsplit[CurrentScan] = 2 * (data & 0x3f);
  252.  
  253.     BackgroundData = ((data&0xc0) >> 6) * 0x55;
  254. }
  255.  
  256.  
  257. /* This selects commercial (high res, arcade) or
  258.                   consumer (low res, astrocade) mode */
  259.  
  260. WRITE_HANDLER( astrocde_mode_w )
  261. {
  262. //    astrocade_mode = data & 0x01;
  263. }
  264.  
  265.  
  266. WRITE_HANDLER( astrocde_vertical_blank_w )
  267. {
  268.     if (VerticalBlank != data)
  269.     {
  270.         VerticalBlank = data;
  271.     }
  272. }
  273.  
  274.  
  275. WRITE_HANDLER( astrocde_colour_register_w )
  276. {
  277.     colors[CurrentScan][offset] = data;
  278.  
  279. #ifdef MAME_DEBUG
  280.     logerror("colors %01x set to %02x\n",offset,data);
  281. #endif
  282. }
  283.  
  284. WRITE_HANDLER( astrocde_colour_block_w )
  285. {
  286.     static int color_reg_num = 7;
  287.  
  288.     astrocde_colour_register_w(color_reg_num,data);
  289.  
  290.     color_reg_num = (color_reg_num - 1) & 7;
  291. }
  292.  
  293.  
  294. WRITE_HANDLER( wow_videoram_w )
  295. {
  296.     if ((offset < 0x4000) && (wow_videoram[offset] != data))
  297.     {
  298.         wow_videoram[offset] = data;
  299.     }
  300. }
  301.  
  302.  
  303. WRITE_HANDLER( astrocde_magic_expand_color_w )
  304. {
  305. #ifdef MAME_DEBUG
  306. //    logerror("%04x: magic_expand_color = %02x\n",cpu_get_pc(),data);
  307. #endif
  308.  
  309.     magic_expand_color = data;
  310. }
  311.  
  312.  
  313. WRITE_HANDLER( astrocde_magic_control_w )
  314. {
  315. #ifdef MAME_DEBUG
  316. //    logerror("%04x: magic_control = %02x\n",cpu_get_pc(),data);
  317. #endif
  318.  
  319.     magic_control = data;
  320.  
  321.     magic_expand_count = 0;    /* reset flip-flop for expand mode on write to this register */
  322.     magic_shift_leftover = 0;    /* reset shift buffer on write to this register */
  323.  
  324.     if (magic_control & 0x04)
  325.         usrintf_showmessage("unsupported MAGIC ROTATE mode");
  326. }
  327.  
  328.  
  329. static void copywithflip(int offset,int data)
  330. {
  331.     int shift,data1;
  332.  
  333.  
  334.     if (magic_control & 0x40)    /* copy backwards */
  335.     {
  336.         int bits,stib,k;
  337.  
  338.         bits = data;
  339.         stib = 0;
  340.         for (k = 0;k < 4;k++)
  341.         {
  342.             stib >>= 2;
  343.             stib |= (bits & 0xc0);
  344.             bits <<= 2;
  345.         }
  346.  
  347.         data = stib;
  348.     }
  349.  
  350.     shift = magic_control & 3;
  351.     data1 = 0;
  352.     if (magic_control & 0x40)    /* copy backwards */
  353.     {
  354.         while (shift > 0)
  355.         {
  356.             data1 <<= 2;
  357.             data1 |= (data & 0xc0) >> 6;
  358.             data <<= 2;
  359.             shift--;
  360.         }
  361.     }
  362.     else
  363.     {
  364.         while (shift > 0)
  365.         {
  366.             data1 >>= 2;
  367.             data1 |= (data & 0x03) << 6;
  368.             data >>= 2;
  369.             shift--;
  370.         }
  371.     }
  372.     data |= magic_shift_leftover;
  373.     magic_shift_leftover = data1;
  374.  
  375.     if (magic_control & 0x30)
  376.     {
  377.         /* TODO: the collision detection should be made */
  378.         /* independently for each of the four pixels    */
  379.  
  380.         if (data && wow_videoram[offset])
  381.             collision |= 0xff;
  382.         else collision &= 0x0f;
  383.     }
  384.  
  385.     if (magic_control & 0x20) data ^= wow_videoram[offset];    /* draw in XOR mode */
  386.     else if (magic_control & 0x10) data |= wow_videoram[offset];    /* draw in OR mode */
  387.     wow_videoram_w(offset,data);
  388. }
  389.  
  390.  
  391. WRITE_HANDLER( wow_magicram_w )
  392. {
  393.     if (magic_control & 0x08)    /* expand mode */
  394.     {
  395.         int bits,bibits,k;
  396.  
  397.         bits = data;
  398.         if (magic_expand_count) bits <<= 4;
  399.         bibits = 0;
  400.         for (k = 0;k < 4;k++)
  401.         {
  402.             bibits <<= 2;
  403.             if (bits & 0x80) bibits |= (magic_expand_color >> 2) & 0x03;
  404.             else bibits |= magic_expand_color & 0x03;
  405.             bits <<= 1;
  406.         }
  407.  
  408.         copywithflip(offset,bibits);
  409.  
  410.         magic_expand_count ^= 1;
  411.     }
  412.     else copywithflip(offset,data);
  413. }
  414.  
  415.  
  416. WRITE_HANDLER( astrocde_pattern_board_w )
  417. {
  418.     static int src;
  419.     static int mode;    /*  bit 0 = direction
  420.                             bit 1 = expand mode
  421.                             bit 2 = constant
  422.                             bit 3 = flush
  423.                             bit 4 = flip
  424.                             bit 5 = flop */
  425.     static int skip;    /* bytes to skip after row copy */
  426.     static int dest;
  427.     static int length;    /* row length */
  428.     static int loops;    /* rows to copy - 1 */
  429.     unsigned char *RAM = memory_region(REGION_CPU1);
  430.  
  431.  
  432.     switch (offset)
  433.     {
  434.         case 0:
  435.             src = data;
  436.             break;
  437.         case 1:
  438.             src = src + data * 256;
  439.             break;
  440.         case 2:
  441.             mode = data & 0x3f;            /* register is 6 bit wide */
  442.             break;
  443.         case 3:
  444.             skip = data;
  445.             break;
  446.         case 4:
  447.             dest = skip + data * 256;    /* register 3 is shared between skip and dest */
  448.             break;
  449.         case 5:
  450.             length = data;
  451.             break;
  452.         case 6:
  453.             loops = data;
  454.             break;
  455.     }
  456.  
  457.     if (offset == 6)    /* trigger blit */
  458.     {
  459.         int i,j;
  460.  
  461. #ifdef MAME_DEBUG
  462. //        logerror("%04x: blit src %04x mode %02x skip %d dest %04x length %d loops %d\n",
  463. //            cpu_get_pc(),src,mode,skip,dest,length,loops);
  464. #endif
  465.  
  466.         /* Kludge: have to steal some cycles from the Z80 otherwise text
  467.            scrolling in Gorf is too fast. */
  468.         z80_ICount -= 4 * (length+1) * (loops+1);
  469.  
  470.         for (i = 0; i <= loops;i++)
  471.         {
  472.             for (j = 0;j <= length;j++)
  473.             {
  474.                 if (!(mode & 0x08) || j < length)
  475.                 {
  476.                     if (mode & 0x01)            /* Direction */
  477.                         RAM[src]=RAM[dest];
  478.                     else
  479.                         if (dest >= 0) cpu_writemem16(dest,RAM[src]);    /* ASG 971005 */
  480.                 }
  481.                 /* close out writes in case of shift... I think this is wrong */
  482.                 else if (j == length)
  483.                     if (dest >= 0) cpu_writemem16(dest,0);
  484.  
  485.                 if ((j & 1) || !(mode & 0x02))  /* Expand Mode - don't increment source on odd loops */
  486.                     if (mode & 0x04) src++;        /* Constant mode - don't increment at all! */
  487.  
  488.                 if (mode & 0x20) dest++;        /* copy forwards */
  489.                 else dest--;                    /* backwards */
  490.             }
  491.  
  492.             if ((j & 1) && (mode & 0x02))        /* always increment source at end of line */
  493.                 if (mode & 0x04) src++;            /* Constant mode - don't increment at all! */
  494.  
  495.             if ((mode & 0x08) && (mode & 0x04)) /* Correct src if in flush mode */
  496.                 src--;                          /* and NOT in Constant mode */
  497.  
  498.             if (mode & 0x20) dest--;            /* copy forwards */
  499.             else dest++;                        /* backwards */
  500.  
  501.             dest += (int)((signed char)skip);    /* extend the sign of the skip register */
  502.  
  503.             /* Note: actually the hardware doesn't handle the sign of the skip register, */
  504.             /* when incrementing the destination address the carry bit is taken from the */
  505.             /* mode register. To faithfully emulate the hardware I should do: */
  506. #if 0
  507.             {
  508.                 int lo,hi;
  509.  
  510.                 lo = dest & 0x00ff;
  511.                 hi = dest & 0xff00;
  512.                 lo += skip;
  513.                 if (mode & 0x10)
  514.                 {
  515.                     if (lo < 0x100) hi -= 0x100;
  516.                 }
  517.                 else
  518.                 {
  519.                     if (lo > 0xff) hi += 0x100;
  520.                 }
  521.                 dest = hi | (lo & 0xff);
  522.             }
  523. #endif
  524.         }
  525.     }
  526. }
  527.  
  528.  
  529. static void init_star_field(void)
  530. {
  531.     int generator;
  532.     int count,x,y;
  533.  
  534.     generator = 0;
  535.  
  536.     /* this 17-bit shifter with XOR feedback has a period of 2^17-1 iterations */
  537.     for (count = 0;count < RNG_PERIOD;count++)
  538.     {
  539.         int bit1,bit2;
  540.  
  541.         generator <<= 1;
  542.         bit1 = (~generator >> 17) & 1;
  543.         bit2 = (generator >> 5) & 1;
  544.  
  545.         if (bit1 ^ bit2) generator |= 1;
  546.  
  547.         rng[count] = generator & 0x1ffff;
  548.     }
  549.  
  550.  
  551.     /* calculate stars positions */
  552.     count = 0;
  553.     for (y = 0;y < MAX_LINES;y++)
  554.     {
  555.         for (x = -16;x < CLOCKS_PER_LINE-16;x++)    /* perfect values determined with screen shots */
  556.         {
  557.             if (x >= Machine->drv->visible_area.min_x &&
  558.                 x <= Machine->drv->visible_area.max_x &&
  559.                 y >= Machine->drv->visible_area.min_y &&
  560.                 y <= Machine->drv->visible_area.max_y)
  561.             {
  562.                 if ((rng[count] & 0x1fe00) == 0x0fe00)
  563.                     star[x+SCREEN_WIDTH*y] = 1;
  564.                 else
  565.                     star[x+SCREEN_WIDTH*y] = 0;
  566.             }
  567.  
  568.             count++;
  569.         }
  570.     }
  571.  
  572.  
  573.     /* now convert the rng values to Y adjustments that will be used at runtime */
  574.     for (count = 0;count < RNG_PERIOD;count++)
  575.     {
  576.         int r;
  577.  
  578.         r = rng[count];
  579.         rng[count] = (((r >> 12) & 1) << 3) +
  580.                      (((r >>  8) & 1) << 2) +
  581.                      (((r >>  4) & 1) << 1) +
  582.                      (((r >>  0) & 1) << 0);
  583.     }
  584. }
  585.  
  586.  
  587. /* GORF Special Registers
  588.  *
  589.  * These are data writes, done by IN commands
  590.  *
  591.  * The data is placed on the upper bits 8-11 bits of the address bus (B)
  592.  * and is used to drive 2 8 bit addressable latches to control :-
  593.  *
  594.  * IO 15
  595.  *   0 coin counter
  596.  *   1 coin counter
  597.  *   2 Star enable (never written to)
  598.  *   3 Sparkle 1
  599.  *   4 Sparkle 2
  600.  *   5 Sparkle 3
  601.  *   6 Second Amp On/Off ?
  602.  *   7 Drv7
  603.  *
  604.  * IO 16
  605.  *   0
  606.  *   1
  607.  *   2
  608.  *   3
  609.  *   4
  610.  *   5
  611.  *   6
  612.  *   7 Space Cadet Light ?
  613.  *
  614.  */
  615.  
  616. READ_HANDLER( gorf_io_r )
  617. {
  618.     int data;
  619.  
  620.     data = (cpu_get_reg(Z80_BC) >> 8) & 0x0f;
  621.  
  622.     offset = (offset << 3) + (data >> 1);
  623.     data = ~data & 0x01;
  624.  
  625.     switch (offset)
  626.     {
  627.         case 0: coin_counter_w(0,data); break;
  628.         case 1: coin_counter_w(1,data); break;
  629.         case 2: sparkle[CurrentScan][0] = data; break;
  630.         case 3: sparkle[CurrentScan][1] = data; break;
  631.         case 4: sparkle[CurrentScan][2] = data; break;
  632.         case 5: sparkle[CurrentScan][3] = data; break;
  633.     }
  634.  
  635. #ifdef MAME_DEBUG
  636.     logerror("%04x: Latch IO %02x set to %d\n",cpu_get_pc(),offset,data);
  637. #endif
  638.  
  639.     return 0;
  640. }
  641.  
  642.  
  643. /* Wizard of Wor Special Registers
  644.  *
  645.  * These are data writes, done by IN commands
  646.  *
  647.  * The data is placed on the upper bits 8-11 bits of the address bus (A)
  648.  * and is used to drive 1 8 bit addressable latches to control :-
  649.  *
  650.  * IO 15
  651.  *   0 coin counter
  652.  *   1 coin counter
  653.  *   2 Star enable (never written to)
  654.  *   3 Sparkle 1
  655.  *   4 Sparkle 2
  656.  *   5 Sparkle 3
  657.  *   6 n.c.
  658.  *   7 coin counter
  659.  *
  660.  */
  661.  
  662. READ_HANDLER( wow_io_r )
  663. {
  664.     int data;
  665.  
  666.     data = (cpu_get_reg(Z80_AF) >> 8) & 0x0f;
  667.  
  668.     offset = (offset << 3) + (data >> 1);
  669.     data = ~data & 0x01;
  670.  
  671.     switch (offset)
  672.     {
  673.         case 0: coin_counter_w(0,data); break;
  674.         case 1: coin_counter_w(1,data); break;
  675.         case 2: sparkle[CurrentScan][0] = data; break;
  676.         case 3: sparkle[CurrentScan][1] = data; break;
  677.         case 4: sparkle[CurrentScan][2] = data; break;
  678.         case 5: sparkle[CurrentScan][3] = data; break;
  679.         case 7: coin_counter_w(2,data); break;
  680.     }
  681.  
  682. #ifdef MAME_DEBUG
  683.     logerror("%04x: Latch IO %02x set to %d\n",cpu_get_pc(),offset,data);
  684. #endif
  685.  
  686.     return 0;
  687. }
  688.  
  689. /****************************************************************************/
  690.  
  691. void astrocde_vh_stop(void)
  692. {
  693.     free(rng);
  694.     rng = 0;
  695.     free(star);
  696.     star = 0;
  697. }
  698.  
  699. int astrocde_vh_start(void)
  700. {
  701.     rng = malloc(RNG_PERIOD * sizeof(rng[0]));
  702.     star = malloc(SCREEN_WIDTH * MAX_LINES * sizeof(star[0]));
  703.  
  704.     if (!rng || !star)
  705.         return 1;
  706.  
  707.     memset(sparkle,0,sizeof(sparkle));
  708.     CurrentScan = 0;
  709.  
  710.     return 0;
  711. }
  712.  
  713. int astrocde_stars_vh_start(void)
  714. {
  715.     int res;
  716.  
  717.     res = astrocde_vh_start();
  718.  
  719.     sparkle[0][0] = 1;    /* wow doesn't initialize this */
  720.     init_star_field();
  721.  
  722.     return res;
  723. }
  724.  
  725.  
  726.  
  727. /****************************************************************************/
  728.  
  729. void wow_update_line(struct osd_bitmap *bitmap,int line)
  730. {
  731.     /* Copy one line to bitmap, using current color register settings */
  732.  
  733.     int memloc;
  734.     int i,x;
  735.     int data,color;
  736.     int rngoffs;
  737.  
  738.     if (line >= MAX_LINES) return;
  739.  
  740.     rngoffs = MOD_U32_U64_U32( MUL_U64_U32_U32(
  741.             cpu_getcurrentframe() % RNG_PERIOD, CLOCKS_PER_FRAME), RNG_PERIOD);
  742.  
  743.     memloc = line * 80;
  744.  
  745.     for (i = 0; i < 80; i++, memloc++)
  746.     {
  747.         if (line < VerticalBlank)
  748.             data = wow_videoram[memloc];
  749.         else
  750.             data = BackgroundData;
  751.  
  752.         for (x = i*4+3; x >= i*4; x--)
  753.         {
  754.             int pen,scol;
  755.  
  756.             color = data & 0x03;
  757.             if (i < colorsplit[line]) color += 4;
  758.  
  759.             if ((data & 0x03) == 0)
  760.             {
  761.                 if (sparkle[line][0])
  762.                 {
  763.                     if (star[x+SCREEN_WIDTH*line])
  764.                     {
  765.                         scol = rng[(rngoffs + x+CLOCKS_PER_LINE*line) % RNG_PERIOD];
  766.                         pen = (colors[line][color]&~7) + scol/2;
  767.                     }
  768.                     else
  769.                         pen = 0;
  770.                 }
  771.                 else
  772.                     pen = colors[line][color];
  773.             }
  774.             else
  775.             {
  776.                 if (sparkle[line][data & 0x03])
  777.                 {
  778.                     scol = rng[(rngoffs + x+CLOCKS_PER_LINE*line) % RNG_PERIOD];
  779.                     pen = (colors[line][color]&~7) + scol/2;
  780.                 }
  781.                 else
  782.                     pen = colors[line][color];
  783.             }
  784.  
  785.             plot_pixel(bitmap,x,line,Machine->pens[pen]);
  786.  
  787.             data >>= 2;
  788.         }
  789.     }
  790. }
  791.  
  792.  
  793.  
  794. void astrocde_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  795. {
  796.     if (full_refresh)
  797.     {
  798.         int i;
  799.  
  800.         for (i = 0;i < MAX_LINES;i++)
  801.             wow_update_line(bitmap,i);
  802.     }
  803. }
  804.  
  805. void seawolf2_vh_screenrefresh(struct osd_bitmap *bitmap,int full_refresh)
  806. {
  807.     int x,y,centre;
  808.     unsigned char *RAM = memory_region(REGION_CPU1);
  809.  
  810.  
  811.     astrocde_vh_screenrefresh(bitmap,full_refresh);
  812.  
  813.  
  814.     /* Draw a sight */
  815.  
  816.     if(RAM[0xc1fb] != 0)    /* Number of Players */
  817.     {
  818.         /* Yellow sight for Player 1 */
  819.  
  820.         centre = 317 - ((input_port_0_r(0) & 0x3f)-18) * 10;
  821.  
  822.         if (centre<2)   centre=2;
  823.         if (centre>317) centre=317;
  824.  
  825.         for (y=35-10;y<35+11;y++)
  826.             plot_pixel(bitmap, centre, y, Machine->pens[0x77]);
  827.  
  828.            for (x=centre-20;x<centre+21;x++)
  829.             if((x>0) && (x<319))
  830.                 plot_pixel(bitmap, x, 35, Machine->pens[0x77]);
  831.  
  832.  
  833.         /* Red sight for Player 2 */
  834.  
  835.         if(RAM[0xc1fb] == 2)
  836.         {
  837.             centre = 316 - ((input_port_1_r(0) & 0x3f)-18) * 10;
  838.  
  839.             if (centre<1)   centre=1;
  840.             if (centre>316) centre=316;
  841.  
  842.             for (y=33-10;y<33+11;y++)
  843.                 plot_pixel(bitmap, centre, y, Machine->pens[0x58]);
  844.  
  845.             for (x=centre-20;x<centre+21;x++)
  846.                 if((x>0) && (x<319))
  847.                     plot_pixel(bitmap, x, 33, Machine->pens[0x58]);
  848.         }
  849.     }
  850. }
  851.